home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / varie / uae-0_64.lha / uae-0.6.4 / src / memory.c < prev    next >
C/C++ Source or Header  |  1996-09-03  |  13KB  |  553 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * Memory management
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "memory.h"
  15. #include "custom.h"
  16. #include "cia.h"
  17. #include "ersatz.h"
  18. #include "zfile.h"
  19. #include "events.h"
  20. #include "newcpu.h"
  21. #include "compiler.h"
  22.  
  23. #ifdef USE_COMPILER
  24. #include <sys/mman.h>
  25. #endif
  26.  
  27. int ersatzkickfile = 0;
  28.  
  29. int buserr;
  30. addrbank membanks[65536];
  31.  
  32. /* Default memory access functions */
  33.  
  34. int default_check(CPTR a, ULONG b)
  35. {
  36.     return 0;
  37. }
  38.  
  39. UBYTE *default_xlate(CPTR a)
  40. {
  41.     fprintf(stderr, "Your Amiga program just did something terribly stupid\n");
  42.     return 0;
  43. }
  44.  
  45. UWORD default_awget(CPTR addr)
  46. {
  47.     default_xlate(addr);
  48.     return 0;
  49. }
  50.  
  51. ULONG default_alget(CPTR addr)
  52. {
  53.     default_xlate(addr);
  54.     return 0;
  55. }
  56.  
  57. /* A dummy bank that only contains zeros */
  58.  
  59. static ULONG dummy_lget(CPTR) REGPARAM;
  60. static UWORD dummy_wget(CPTR) REGPARAM;
  61. static UBYTE dummy_bget(CPTR) REGPARAM;
  62. static void  dummy_lput(CPTR, ULONG) REGPARAM;
  63. static void  dummy_wput(CPTR, UWORD) REGPARAM;
  64. static void  dummy_bput(CPTR, UBYTE) REGPARAM;
  65. static int   dummy_check(CPTR addr, ULONG size) REGPARAM;
  66.  
  67. ULONG dummy_lget(CPTR addr)
  68. {
  69.     if (illegal_mem) printf("Illegal lget at %08lx pc=%08lx\n",addr,m68k_getpc());
  70.     return 0;
  71. }
  72.  
  73. UWORD dummy_wget(CPTR addr)
  74. {
  75.     if (illegal_mem) printf("Illegal wget at %08lx pc=%08lx\n",addr,m68k_getpc());
  76.     return 0;
  77. }
  78.  
  79. UBYTE dummy_bget(CPTR addr)
  80. {
  81.     if (illegal_mem) printf("Illegal bget at %08lx pc=%08lx\n",addr,m68k_getpc());
  82.     return 0;
  83. }
  84.  
  85. void dummy_lput(CPTR addr, ULONG l)
  86. {
  87.     if (illegal_mem) printf("Illegal lput at %08lx pc=%08lx\n",addr,m68k_getpc());
  88. }
  89. void dummy_wput(CPTR addr, UWORD w)
  90. {
  91.     if (illegal_mem) printf("Illegal wput at %08lx pc=%08lx\n",addr,m68k_getpc());
  92. }
  93. void dummy_bput(CPTR addr, UBYTE b)
  94. {
  95.     if (illegal_mem) printf("Illegal bput at %08lx pc=%08lx\n",addr,m68k_getpc());
  96. }
  97.  
  98. int dummy_check(CPTR addr, ULONG size)
  99. {
  100.     if (illegal_mem) printf("Illegal check at %08lx pc=%08lx\n",addr,m68k_getpc());
  101.     return 0;
  102. }
  103.  
  104. /* Chip memory */
  105.  
  106. ULONG chipmem_mask,kickmem_mask,bogomem_mask;
  107.  
  108. UBYTE *chipmemory;
  109.  
  110. static ULONG chipmem_alget(CPTR) REGPARAM;
  111. static UWORD chipmem_awget(CPTR) REGPARAM;
  112.  
  113. static ULONG chipmem_lget(CPTR) REGPARAM;
  114. static UWORD chipmem_wget(CPTR) REGPARAM;
  115. static UBYTE chipmem_bget(CPTR) REGPARAM;
  116. static void  chipmem_lput(CPTR, ULONG) REGPARAM;
  117. static void  chipmem_wput(CPTR, UWORD) REGPARAM;
  118. static void  chipmem_bput(CPTR, UBYTE) REGPARAM;
  119.  
  120. static int   chipmem_check(CPTR addr, ULONG size) REGPARAM;
  121. static UBYTE *chipmem_xlate(CPTR addr) REGPARAM;
  122.  
  123. ULONG chipmem_alget(CPTR addr)
  124. {
  125.     UBYTE *m;
  126.     addr -= chipmem_start & chipmem_mask;
  127.     addr &= chipmem_size-1;
  128.     m = chipmemory + addr;
  129.     return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) 
  130.         + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
  131. }
  132.  
  133. UWORD chipmem_awget(CPTR addr)
  134. {
  135.     UBYTE *m;
  136.     addr -= chipmem_start & chipmem_mask;
  137.     addr &= chipmem_size-1;
  138.     m = chipmemory + addr;
  139.     return ((UWORD)m[0] << 8) + m[1];
  140. }
  141.  
  142. ULONG chipmem_lget(CPTR addr)
  143. {
  144.     UBYTE *m;
  145.     addr -= chipmem_start & chipmem_mask;
  146.     addr &= chipmem_size-1;
  147.     m = chipmemory + addr;
  148.     return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) 
  149.         + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
  150. }
  151.  
  152. UWORD chipmem_wget(CPTR addr)
  153. {
  154.     UBYTE *m;
  155.     addr -= chipmem_start & chipmem_mask;
  156.     addr &= chipmem_size-1;
  157.     m = chipmemory + addr;
  158.     return ((UWORD)m[0] << 8) + m[1];
  159. }
  160.  
  161. UBYTE chipmem_bget(CPTR addr)
  162. {
  163.     addr -= chipmem_start & chipmem_mask;
  164.     addr &= chipmem_size-1;
  165.     return chipmemory[addr];
  166. }
  167.  
  168. void chipmem_lput(CPTR addr, ULONG l)
  169. {
  170.     UBYTE *m;
  171.     addr -= chipmem_start & chipmem_mask;
  172.     addr &= chipmem_size-1;
  173.     m = chipmemory + addr;
  174.     m[0] = l >> 24;
  175.     m[1] = l >> 16;
  176.     m[2] = l >> 8;
  177.     m[3] = l;
  178. }
  179.  
  180. void chipmem_wput(CPTR addr, UWORD w)
  181. {
  182.     UBYTE *m;
  183.     addr -= chipmem_start & chipmem_mask;
  184.     addr &= chipmem_size-1;
  185.     m = chipmemory + addr;
  186.     m[0] = w >> 8;
  187.     m[1] = w;
  188. }
  189.  
  190. void chipmem_bput(CPTR addr, UBYTE b)
  191. {
  192.     addr -= chipmem_start & chipmem_mask;
  193.     addr &= chipmem_size-1;
  194.     chipmemory[addr] = b;
  195. }
  196.  
  197. int chipmem_check(CPTR addr, ULONG size)
  198. {
  199.     addr -= chipmem_start & chipmem_mask;
  200.     addr &= chipmem_size-1;
  201.     return (addr + size) < chipmem_size;
  202. }
  203.  
  204. UBYTE *chipmem_xlate(CPTR addr)
  205. {
  206.     addr -= chipmem_start & chipmem_mask;
  207.     addr &= chipmem_size-1;
  208.     return chipmemory + addr;
  209. }
  210.  
  211. /* Slow memory */
  212.  
  213. static UBYTE *bogomemory;
  214.  
  215. static ULONG bogomem_alget(CPTR) REGPARAM;
  216. static UWORD bogomem_awget(CPTR) REGPARAM;
  217. static ULONG bogomem_lget(CPTR) REGPARAM;
  218. static UWORD bogomem_wget(CPTR) REGPARAM;
  219. static UBYTE bogomem_bget(CPTR) REGPARAM;
  220. static void  bogomem_lput(CPTR, ULONG) REGPARAM;
  221. static void  bogomem_wput(CPTR, UWORD) REGPARAM;
  222. static void  bogomem_bput(CPTR, UBYTE) REGPARAM;
  223. static int  bogomem_check(CPTR addr, ULONG size) REGPARAM;
  224. static UBYTE *bogomem_xlate(CPTR addr) REGPARAM;
  225.  
  226. ULONG bogomem_alget(CPTR addr)
  227. {
  228.     UBYTE *m;
  229.     addr -= bogomem_start & bogomem_mask;
  230.     addr &= bogomem_size-1;
  231.     m = bogomemory + addr;
  232.     return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) 
  233.         + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
  234. }
  235.  
  236. UWORD bogomem_awget(CPTR addr)
  237. {
  238.     UBYTE *m;
  239.     addr -= bogomem_start & bogomem_mask;
  240.     addr &= bogomem_size-1;
  241.     m = bogomemory + addr;
  242.     return ((UWORD)m[0] << 8) + m[1];
  243. }
  244.  
  245. ULONG bogomem_lget(CPTR addr)
  246. {
  247.     UBYTE *m;
  248.     addr -= bogomem_start & bogomem_mask;
  249.     addr &= bogomem_size-1;
  250.     m = bogomemory + addr;
  251.     return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) 
  252.         + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
  253. }
  254.  
  255. UWORD bogomem_wget(CPTR addr)
  256. {
  257.     UBYTE *m;
  258.     addr -= bogomem_start & bogomem_mask;
  259.     addr &= bogomem_size-1;
  260.     m = bogomemory + addr;
  261.     return ((UWORD)m[0] << 8) + m[1];
  262. }
  263.  
  264. UBYTE bogomem_bget(CPTR addr)
  265. {
  266.     addr -= bogomem_start & bogomem_mask;
  267.     addr &= bogomem_size-1;
  268.     return bogomemory[addr];
  269. }
  270.  
  271. void bogomem_lput(CPTR addr, ULONG l)
  272. {
  273.     UBYTE *m;
  274.     addr -= bogomem_start & bogomem_mask;
  275.     addr &= bogomem_size-1;
  276.     m = bogomemory + addr;
  277.     m[0] = l >> 24;
  278.     m[1] = l >> 16;
  279.     m[2] = l >> 8;
  280.     m[3] = l;
  281. }
  282.  
  283. void bogomem_wput(CPTR addr, UWORD w)
  284. {
  285.     UBYTE *m;
  286.     addr -= bogomem_start & bogomem_mask;
  287.     addr &= bogomem_size-1;
  288.     m = bogomemory + addr;
  289.     m[0] = w >> 8;
  290.     m[1] = w;
  291. }
  292.  
  293. void bogomem_bput(CPTR addr, UBYTE b)
  294. {
  295.     addr -= bogomem_start & bogomem_mask;
  296.     addr &= bogomem_size-1;
  297.     bogomemory[addr] = b;
  298. }
  299.  
  300. int bogomem_check(CPTR addr, ULONG size)
  301. {
  302.     addr -= bogomem_start & (bogomem_size-1);
  303.     addr &= bogomem_size-1;
  304.     return (addr + size) < bogomem_size;
  305. }
  306.  
  307. UBYTE *bogomem_xlate(CPTR addr)
  308. {
  309.     addr -= bogomem_start & (bogomem_size-1);
  310.     addr &= bogomem_size-1;
  311.     return bogomemory + addr;
  312. }
  313.  
  314. /* Kick memory */
  315.  
  316. static int zkickfile = 0;
  317. UBYTE *kickmemory;
  318.  
  319. static ULONG kickmem_alget(CPTR) REGPARAM;
  320. static UWORD kickmem_awget(CPTR) REGPARAM;
  321. static ULONG kickmem_lget(CPTR) REGPARAM;
  322. static UWORD kickmem_wget(CPTR) REGPARAM;
  323. static UBYTE kickmem_bget(CPTR) REGPARAM;
  324. static void  kickmem_lput(CPTR, ULONG) REGPARAM;
  325. static void  kickmem_wput(CPTR, UWORD) REGPARAM;
  326. static void  kickmem_bput(CPTR, UBYTE) REGPARAM;
  327. static int  kickmem_check(CPTR addr, ULONG size) REGPARAM;
  328. static UBYTE *kickmem_xlate(CPTR addr) REGPARAM;
  329.  
  330. ULONG kickmem_alget(CPTR addr)
  331. {
  332.     UBYTE *m;
  333.     addr -= kickmem_start & kickmem_mask;
  334.     addr &= kickmem_size-1;
  335.     m = kickmemory + addr;
  336.     return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) 
  337.         + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
  338. }
  339.  
  340. UWORD kickmem_awget(CPTR addr)
  341. {
  342.     UBYTE *m;
  343.     addr -= kickmem_start & kickmem_mask;
  344.     addr &= kickmem_size-1;
  345.     m = kickmemory + addr;
  346.     return ((UWORD)m[0] << 8) + m[1];
  347. }
  348.  
  349. ULONG kickmem_lget(CPTR addr)
  350. {
  351.     UBYTE *m;
  352.     addr -= kickmem_start & kickmem_mask;
  353.     addr &= kickmem_size-1;
  354.     m = kickmemory + addr;
  355.     return (((ULONG)m[0] << 24) + ((ULONG)m[1] << 16) 
  356.         + ((ULONG)m[2] << 8) + ((ULONG)m[3]));
  357. }
  358.  
  359. UWORD kickmem_wget(CPTR addr)
  360. {
  361.     UBYTE *m;
  362.     addr -= kickmem_start & kickmem_mask;
  363.     addr &= kickmem_size-1;
  364.     m = kickmemory + addr;
  365.     return ((UWORD)m[0] << 8) + m[1];
  366. }
  367.  
  368. UBYTE kickmem_bget(CPTR addr)
  369. {
  370.     addr -= kickmem_start & kickmem_mask;
  371.     addr &= kickmem_size-1;
  372.     return kickmemory[addr];
  373. }
  374.  
  375. void kickmem_lput(CPTR addr, ULONG b)
  376. {
  377.     if (illegal_mem) printf("Illegal kickmem lput at %08lx pc=%08lx\n",addr,m68k_getpc());
  378. }
  379.  
  380. void kickmem_wput(CPTR addr, UWORD b)
  381. {
  382.     if (illegal_mem) printf("Illegal kickmem wput at %08lx pc=%08lx\n",addr,m68k_getpc());
  383. }
  384.  
  385. void kickmem_bput(CPTR addr, UBYTE b)
  386. {
  387.     if (illegal_mem) printf("Illegal kickmem lput at %08lx pc=%08lx\n",addr,m68k_getpc());
  388. }
  389.  
  390. int kickmem_check(CPTR addr, ULONG size)
  391. {
  392.     addr -= kickmem_start & (kickmem_size-1);
  393.     addr &= kickmem_size-1;
  394.     return (addr + size) < kickmem_size;
  395. }
  396.  
  397. UBYTE *kickmem_xlate(CPTR addr)
  398. {
  399.     addr -= kickmem_start & (kickmem_size-1);
  400.     addr &= kickmem_size-1;
  401.     return kickmemory + addr;
  402. }
  403.  
  404. static int load_kickstart(void)
  405. {
  406.     int i;
  407.     ULONG cksum = 0, prevck = 0;
  408.     unsigned char buffer[8];
  409.     
  410.     FILE *f = zfile_open(romfile, "rb");
  411.     
  412.     if (f == NULL) {    
  413.         fprintf(stderr, "No Kickstart ROM found.\n");
  414.     return 0;
  415.     }
  416.     
  417.     fread(buffer, 1, 8, f);
  418.     if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) {
  419.     fprintf(stderr, "You seem to have a ZKick file there... You probably lose.\n");
  420.     zkickfile = 1;
  421.     } else 
  422.     fseek(f, 0, SEEK_SET);
  423.     
  424.     i = fread(kickmemory, 1, kickmem_size, f);
  425.     if (i == kickmem_size/2) {
  426.     fprintf(stderr, "Warning: Kickstart is only 256K.\n");
  427.     memcpy (kickmemory + kickmem_size/2, kickmemory, kickmem_size/2);
  428.     } else if (i != kickmem_size) {
  429.     fprintf(stderr, "Error while reading Kickstart.\n");
  430.     return 0;
  431.     }
  432.     zfile_close (f);
  433.     
  434.     for (i = 0; i < kickmem_size; i+=4) {
  435.     ULONG data = kickmemory[i]*65536*256 + kickmemory[i+1]*65536 + kickmemory[i+2]*256 + kickmemory[i+3];
  436.     cksum += data;
  437.     if (cksum < prevck)
  438.         cksum++;
  439.     prevck = cksum;
  440.     }
  441.     if (cksum != 0xFFFFFFFF) {
  442.     fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
  443.     }
  444.     return 1;
  445. }
  446.  
  447. /* Address banks */
  448.  
  449. addrbank dummy_bank = {
  450.     default_alget, default_awget,
  451.     dummy_lget, dummy_wget, dummy_bget,
  452.     dummy_lput, dummy_wput, dummy_bput,
  453.     default_xlate, dummy_check
  454. };
  455.  
  456. addrbank chipmem_bank = {
  457.     chipmem_alget, chipmem_awget,
  458.     chipmem_lget, chipmem_wget, chipmem_bget,
  459.     chipmem_lput, chipmem_wput, chipmem_bput,
  460.     chipmem_xlate, chipmem_check
  461. };
  462.  
  463. addrbank bogomem_bank = {
  464.     bogomem_alget, bogomem_awget,
  465.     bogomem_lget, bogomem_wget, bogomem_bget,
  466.     bogomem_lput, bogomem_wput, bogomem_bput,
  467.     bogomem_xlate, bogomem_check
  468. };
  469.  
  470. addrbank kickmem_bank = {
  471.     kickmem_alget, kickmem_awget,
  472.     kickmem_lget, kickmem_wget, kickmem_bget,
  473.     kickmem_lput, kickmem_wput, kickmem_bput,
  474.     kickmem_xlate, kickmem_check
  475. };
  476.  
  477. char *address_space, *good_address_map;
  478. int good_address_fd;
  479.  
  480. void memory_init(void)
  481. {
  482.     char buffer[4096];
  483.     char *nam;
  484.     int i, fd;
  485.     buserr = 0;
  486.  
  487.     chipmem_mask = chipmem_size - 1;
  488.     kickmem_mask = kickmem_size - 1;
  489.     bogomem_mask = bogomem_size - 1;
  490.     
  491. #ifdef USE_COMPILER
  492.     fd = open("/dev/zero", O_RDWR);
  493.     good_address_map = mmap(NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
  494.     address_space = mmap(NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
  495.     chipmemory = mmap(address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
  496.     kickmemory = mmap(address_space + 0xF80000, 0x80000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0);
  497.  
  498.     close(fd);
  499.  
  500.     good_address_fd = open(nam = tmpnam(NULL), O_CREAT|O_RDWR, 0600);
  501.     memset(buffer,1,sizeof(buffer));
  502.     write(good_address_fd, buffer,sizeof(buffer));
  503.     unlink(nam);
  504.  
  505.     for (i = 0; i < chipmem_size; i += 4096)
  506.     mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE,
  507.          good_address_fd, 0);
  508.     for (i = 0; i < kickmem_size; i += 4096)
  509.     mmap(good_address_map + i + 0x1000000 - kickmem_size, 4096, PROT_READ,
  510.          MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
  511. #else
  512.     chipmemory = (UBYTE *)malloc(chipmem_size);
  513.     kickmemory = (UBYTE *)malloc(kickmem_size);
  514. #endif
  515.  
  516.     for(i = 0; i < 65536; i++)
  517.     membanks[i] = dummy_bank;
  518.     
  519.     /* Map the chipmem into all of the lower 16MB */
  520.     map_banks(&chipmem_bank, 0x00, 256);
  521.     map_banks(&custom_bank, 0xC0, 0x20);
  522.     map_banks(&cia_bank, 0xA0, 32);
  523.     map_banks(&clock_bank, 0xDC, 1);
  524.     
  525.     if (bogomem_size > 0) {
  526.     bogomemory = (UBYTE *)malloc(bogomem_size);
  527.         map_banks(&bogomem_bank, 0xC0, bogomem_size >> 16);
  528.     }
  529.  
  530.     map_banks(&rtarea_bank, 0xF0, 1); 
  531.     if (!load_kickstart()) {
  532.     init_ersatz_rom(kickmemory);
  533.     ersatzkickfile = 1;
  534.     }
  535.     if (zkickfile)
  536.     map_banks(&kickmem_bank, 0x20, 8);
  537.     
  538.     map_banks(&kickmem_bank, 0xF8, 8);
  539.     if (!zkickfile)
  540.     map_banks(&expamem_bank, 0xE8, 1);
  541. }
  542.  
  543. void map_banks(addrbank *bank, int start, int size)
  544. {
  545.     int bnr;
  546.     int hioffs = 0;
  547. #if 0 && CPU_LEVEL < 2
  548.     for (hioffs = 0; hioffs < 256; hioffs++)
  549. #endif
  550.     for (bnr = start; bnr < start+size; bnr++) 
  551.         membanks[bnr + hioffs * 256] = *bank;
  552. }
  553.